package com.example.demo.config;

import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;

/**
 * <pre> api接口定义 </pre>
 * @author liangxn
 * @date 2019/8/18
 * @description
 */
@Configuration("swaggerConfig4demo")
@ConditionalOnProperty(name = "swagger.enable", havingValue = "true")
@EnableSwagger2
@EnableSwaggerBootstrapUI
@ConfigurationProperties(prefix = "swagger")
public class SwaggerConfig {
    /**
     * 是否启用
     */
    private Boolean enable;

    /**
     * 组名
     */
    private String groupName = "demo-api";

    /**
     * 标题
     */
    private String title = "demo";
    /**
     * 描述
     */
    private String description = "demo项目的接口文档";
    /**
     * 团队地址
     */
    private String termsOfServiceUrl;
    /**
     * 作者
     */
    private String contactName;
    /**
     * 邮箱
     */
    private String contactEmail;
    /**
     * /版本
     */
    private String version;
    /**
     * 基础package
     */
    private String basePackage = "com.example.demo.controller";

    @Bean("createRestApi4demo")
    public Docket createRestApi() {
        System.out.println("swagger title:"+title+",description:"+description);

        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .groupName(groupName)
                .select()
                //直接指定到控制层
                .apis(RequestHandlerSelectors.basePackage(basePackage))
                // .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                .paths(PathSelectors.any())
                .build()
                //配置鉴权信息
                .securitySchemes(securitySchemes())
                .securityContexts(securityContexts())
                //.globalOperationParameters(pars)
                .enable(true);
    }


    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title(title)
                .description(description)
                .termsOfServiceUrl(termsOfServiceUrl)
                .contact(new Contact(contactName, "", contactEmail))
                .version(version)
                .build();
    }

    private List<ApiKey> securitySchemes() {
        Set<ApiKey> singleton = Collections.singleton(new ApiKey("BearerToken", "Authorization", "header"));
        return new ArrayList<>(singleton);
    }

    private List<SecurityContext> securityContexts() {
        Set<SecurityContext> singleton = Collections.singleton(SecurityContext.builder()
                .securityReferences(defaultAuth())
                .forPaths(PathSelectors.regex("^(?!auth).*$"))
                .build());
        return new ArrayList<>(singleton);
    }

    private List<SecurityReference> defaultAuth() {
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;

        Set<SecurityReference> authorization = Collections.singleton(new SecurityReference("BearerToken", authorizationScopes));
        return new ArrayList<>(authorization);
    }

    public Boolean getEnable() {
        return enable;
    }

    public void setEnable(Boolean enable) {
        this.enable = enable;
    }

    public String getGroupName() {
        return groupName;
    }

    public void setGroupName(String groupName) {
        this.groupName = groupName;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getTermsOfServiceUrl() {
        return termsOfServiceUrl;
    }

    public void setTermsOfServiceUrl(String termsOfServiceUrl) {
        this.termsOfServiceUrl = termsOfServiceUrl;
    }

    public String getContactName() {
        return contactName;
    }

    public void setContactName(String contactName) {
        this.contactName = contactName;
    }

    public String getContactEmail() {
        return contactEmail;
    }

    public void setContactEmail(String contactEmail) {
        this.contactEmail = contactEmail;
    }

    public String getVersion() {
        return version;
    }

    public void setVersion(String version) {
        this.version = version;
    }

    public String getBasePackage() {
        return basePackage;
    }

    public void setBasePackage(String basePackage) {
        this.basePackage = basePackage;
    }
}